import Component from "../Component.js";
import Socket from "../../experience/utils/Socket.js";
import Type from "../../experience/db/Type.js";
import Net from "../../experience/api/Net.js";

const Feature = ol.Feature;
const Point = ol.geom.Point;
const LineString = ol.geom.LineString;
const Text = ol.style.Text;
const Fill = ol.style.Fill;
const Style = ol.style.Style;
const Icon = ol.style.Icon;
const Stroke = ol.style.Stroke;

// 用于解决四方向分站定位的测试类
export default class PersonV2 extends Component {
    constructor() { 
        super();

        const self = this, config = this.algo.getConfig();
        if (config === null) return;

        this.net = new Net();
        let src = "../../assets/images/person/nickname_green.png";
        this.icon = new Icon({ src: src, scale: 0.3});
        src = "../../assets/images/person/rectangle.png";
        this.rect = new Style({ image: new Icon({ src: src, scale: 0.1}) });
        this.pinkStroke = new Stroke({ width: 2, color: "pink" });

        // 选择器选中人员后,开启轨迹线功能
        this.moves = []; this.selectedRfid = null;
        this.emitter.on("person-selected", () => {
            this.selectedRfid = this.emitter.params[0];
            this.moves = [];
            this.toast("开启人员轨迹功能。");

            // 点击Esc取消轨迹功能
            window.onkeydown = function (event) {
                if (event.defaultPrevented) return;

                let handled = false;
                if (event.key === "Escape") {
                    handled = true;
                    self.moves = [];
                    self.selectedRfid = null;
                    self.drawer.source(Type.Modify).clear();
                    self.toast("关闭人员轨迹功能。");
                    window.onkeydown = null;
                }

                if (handled) event.preventDefault();
            };
        });

        // 获取人员定位分站数据
        this.positions = new Map();
        this.api.getPositions({ meta_id: config.meta_id, type: "kalafina" }).then(p => {
            for (const data of p.data) {
                this.positions.set(data.node_id, data);
            }
        });

        // 设置音频资源
        this.loadedaudiodata = false;
        this.audio = document.getElementById('alarm-music');
        this.audio.src = "../../assets/audio/alarm.wav";
        this.audio.onloadeddata = () => { this.loadedaudiodata = true; };
        this.audio.onended = () => { console.log("播放完毕..."); };
    }

    alarming() {
        // 这里必须得等待音频文件加载完毕
        if (this.loadedaudiodata) {
            // 每次播放间隔为2秒
            setTimeout(() => {
                this.audio.play();
            }, 2000);
        }
    }

    async draw(persons) {
        let alarmnum = 0, warningnum = 0;
        const params = [], url = "http://127.0.0.1:8005/api/alarm";
        const wv2s = await this.db.operation(Type.WarningV2, 'getAll');
        
        this.drawer.source(Type.Person).clear();
        this.$$("#personv2-total").html(`总人数: ${persons.length}`);
        persons.forEach(person => {
            const rdid = parseInt(person.rdid);
            const position = this.positions.get(rdid);
            if (position === undefined) return;

            const x = position.x + person.posx, y = position.y + person.posy;
            const nx = this.algo.normalX(x), ny = this.algo.normalY(y);

            // 这里既要显示图标,又要显示rfid
            const feature = new Feature();
            feature.setId(person.rfid);
            feature.set("type", Type.Person);
            feature.setStyle(new Style({
                image: this.icon,
                text: new Text({
                    text: `${person.rfid}`,
                    fill: new Fill({ color: 'white' }),
                    font: `normal 8px "iconfont"`,
                    textAlign: 'center',
                    textBaseline: 'middle',
                    offsetX: 0, offsetY: 10
                })
            }));
            feature.setGeometry(new Point([nx, ny]));
            this.drawer.source(Type.Person).addFeature(feature);

            // 如果人员被选中,开启人员轨迹功能
            if (this.selectedRfid === person.rfid) {
                // 在被选中人员的外圈画个圆
                const rect = new Feature()
                rect.setStyle(this.rect);
                rect.setGeometry(new Point([nx, ny]));
                this.drawer.source(Type.Person).addFeature(rect);

                // 描画经过的轨迹
                this.moves.push([nx,ny]);
                if (this.moves.length > 100) {
                    this.moves.shift();
                }
                this.drawer.source(Type.Modify).clear();
                const track = new Feature();
                track.setStyle(new Style({ stroke: this.pinkStroke }));
                track.setGeometry(new LineString(this.moves));
                this.drawer.source(Type.Modify).addFeature(track);
            }

            // 这里判断人员是否进入了预警区域
            for (const w of wv2s) {
                if (x >= w.left && x <= w.right && y >= w.bottom && y <= w.top) {
                    // 先通过外框进行过滤
                    const wf = this.drawer.source(Type.WarningV2).getFeatureById(w.id);
                    if (wf === null) continue;
                    
                    // 然后再进行点和面的关系判断
                    const pt = feature.getGeometry().getCoordinates();
                    const flag = wf.getGeometry().intersectsCoordinate(pt);
                    const type = wf.get('dxftype');
                    if (flag) {
                        // 如果满足在预警区域里,需要将其将入接口参数
                        if (type === "alarm") alarmnum += 1;
                        if (type === "warning") warningnum += 1;
                        params.push(person.rfid);
                        break;
                    }
                }
            }
        });

        // 如果有人员在预警区域内部,需要网页播报语音
        if (params.length > 0) {
            this.alarming();
        }

        // 设置显示数目
        this.$$("#personv2-warning").html(`预警人数: ${warningnum}`);
        this.$$("#personv2-alarm").html(`报警人数: ${alarmnum}`);

        // 将告警结果发送给服务器
        const resp = await this.net.post(url, params);
        console.log(resp);
    }

    template() {  
        const div = `
            <div id="vehicle">
                <div class="vehicle-item"><span id="personv2-total">总人数: 0</span></div>
                <div class="vehicle-item"><span id="personv2-warning">预警人数: 0</span></div>
                <div class="vehicle-item"><span id="personv2-alarm">报警人数: 0</span></div>
            </div>
        `;
        this.$$("#article").append(div);
    }

    control() {
        setTimeout(() => {
            this.socket = new Socket("ws://${IP}:1234");
            this.socket.create(async (data) => {
                const json = JSON.parse(data);
                await this.draw(json.items);
            });
        }, 1500);
    }
}